package com.szakul.pdf.repository;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.util.Version;


public class LuceneRepository {

	private static final Logger LOGGER = Logger.getLogger(LuceneRepository.class);
	
	private static NIOFSDirectory idx; 
	private static IndexWriter writer;
	
    /**
     * Context initializer.
     * 
     * @return context
     * @throws NamingException exception
     */
    protected static Context initContext() throws NamingException {
        return new InitialContext();
    }
	

    public static String getRepositoryPath() {
        String repository = "E:\\java\\PdfViewer\\pdfs";
        try {
            Context context = initContext();
            repository = (String) context.lookup("java:comp/env/repository/path");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        
        System.out.println("Repository: " + repository);
        
        return repository;
    }
	
	
    protected String getLucenePath() {
        String repository = "E:\\java\\PdfViewer\\luceneRepository\\pdf.idx";
        try {
            Context context = initContext();
            repository = (String) context.lookup("java:comp/env/lucene/output/path");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return repository;
    }	
	
	
    private  Directory getDirectory() throws IOException {
    	
    	if(idx == null) {
    		idx = new NIOFSDirectory(new File(getLucenePath()));	
    	}
		return idx;
    }
	
    
    public static List<File> getAllFiles() {
      
    	File folder = new File(getRepositoryPath());
        File[] listOfFiles = folder.listFiles();
        List<File> fileList = new ArrayList<File>();
         
        for (int i = 0; i < listOfFiles.length; i++) {
          if (listOfFiles[i].isFile()) {
            LOGGER.debug("File " + listOfFiles[i].getName());
            fileList.add(listOfFiles[i]);
          } 
        }
    
        return fileList;
    	
    }
    
    private void initRepository() {
    	
    	List<File> fileList = getAllFiles();
    	
    	StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);

    	
    	try {
			writer = new IndexWriter(getDirectory(), analyzer, true,
				        IndexWriter.MaxFieldLength.UNLIMITED);
	
			for(File file: fileList) {
				Document luceneDocument = LucenePDFDocument.getDocument(file);
				LOGGER.debug("File: " + file.getName() + " added");
				writer.addDocument(luceneDocument);
				
			}
			
            writer.optimize();
            writer.close();

			
			

		} catch (CorruptIndexException e) {
			
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}


    	
    }
    


	/**
	 * Searches for the given string in the "content" field
	 */
	private List<File> search(Searcher searcher, String queryString)
			throws ParseException, IOException {

		List<File> result = new ArrayList<File>();
		// Build a Query object
		Query query = new QueryParser(Version.LUCENE_29, "contents",
				new StandardAnalyzer(Version.LUCENE_29)).parse(queryString);

		// Search for the query
		TopDocs hits = searcher.search(query, 100);
		ScoreDoc[] scoreDocs = hits.scoreDocs;
		for (int n = 0; n < scoreDocs.length; ++n) {
			ScoreDoc sd = scoreDocs[n];
			float score = sd.score;
			int docId = sd.doc;
			Document d = searcher.doc(docId);
			String fileName = d.get("name");
			LOGGER.debug("score: " + score + " file " + fileName);
			result.add(new File(fileName));

		}
		
		return result;

	}


	public List<File> search(String world) {
		try {
			Searcher searcher = new IndexSearcher(getDirectory(), true);
			return search(searcher, world);
			
			
		} catch (CorruptIndexException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		} catch (ParseException e) {
			
			e.printStackTrace();
		}
		
		return Collections.emptyList();
		
	}
	
    
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		LuceneRepository test = new LuceneRepository();
		//test.initRepository();


			
		test.search("jboss");

	}

}
